﻿using System;
using System.Data;

namespace CSW.Framework.Linq.SchemaModel
{
    /// <summary>
    /// Table column model.
    /// </summary>
    public class TableColumn
    {
        private SqlDbType? m_SqlDbType;

        /// <summary>
        /// Gets or sets the name of the column.
        /// </summary>
        /// <value>The name of the column.</value>
        public string ColumnName { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this column is computed.
        /// </summary>
        /// <value><c>true</c> if this column is computed; otherwise, <c>false</c>.</value>
        public bool IsComputed { get; set; }

        /// <summary>
        /// Gets the <see cref="SqlDbType"/>.
        /// </summary>
        /// <value>The <see cref="SqlDbType"/>.</value>
        public SqlDbType SqlDbType
        {
            get 
            {
                if (m_SqlDbType == null)
                {
                    switch (DbDataType)
                    {
                        case "varchar":
                            m_SqlDbType = SqlDbType.VarChar;
                            break;

                        case "nvarchar":
                            m_SqlDbType = SqlDbType.NVarChar;
                            break;

                        case "int":
                            m_SqlDbType = SqlDbType.Int;
                            break;

                        case "bit":
                            m_SqlDbType = SqlDbType.Bit;
                            break;

                        case "datetime":
                            m_SqlDbType = SqlDbType.DateTime;
                            break;

                        case "money":
                            m_SqlDbType = SqlDbType.Money;
                            break;

                        case "timestamp":
                            m_SqlDbType = SqlDbType.Timestamp;
                            break;

                        case "varbinary":
                            m_SqlDbType = SqlDbType.VarBinary;
                            break;

                        case "rowversion":
                            m_SqlDbType = SqlDbType.VarBinary;
                            break;

                        default:
                            throw new NotSupportedException(string.Format("DbType '{0}' not support.", DbDataType));
                    }
                }

                return m_SqlDbType.Value;
            }
        }

        /// <summary>
        /// Gets or sets the database data type.
        /// </summary>
        /// <value>The database data type.</value>
        public string DbDataType { get; set; }

        /// <summary>
        /// Gets or sets the default value.
        /// </summary>
        /// <value>The default value.</value>
        public string DefaultValue { get; set; }

        /// <summary>
        /// Gets or sets the character max length.
        /// </summary>
        /// <value>The character max length.</value>
        public int? CharacterMaxLength { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this column is a key.
        /// </summary>
        /// <value><c>true</c> if this column is a key; otherwise, <c>false</c>.</value>
        public bool IsKey { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this column is an identity.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this column is an identity; otherwise, <c>false</c>.
        /// </value>
        public bool IsIdentity { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this column is read only.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this column is read only; otherwise, <c>false</c>.
        /// </value>
        public bool IsReadOnly { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this column is nullable.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this column is nullable; otherwise, <c>false</c>.
        /// </value>
        public bool IsNullable { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether this column is a row version.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this column is a row version; otherwise, <c>false</c>.
        /// </value>
        public bool IsRowVersion { get; set; }

        /// <summary>
        /// Gets or sets the Foreign Key ID.
        /// </summary>
        /// <value>The Foreign Key ID.</value>
        public int? FKID { get; set; }

        /// <summary>
        /// Gets or sets the Foreign Key table schema.
        /// </summary>
        /// <value>The Foreign Key table schema.</value>
        public string FKTableSchema { get; set; }

        /// <summary>
        /// Gets or sets the name of the Foreign Key table.
        /// </summary>
        /// <value>The name of the Foreign Key table.</value>
        public string FKTableName { get; set; }

        /// <summary>
        /// Gets or sets the name of the Foreign Key table column.
        /// </summary>
        /// <value>The name of the Foreign Key table column.</value>
        public string FKTableColumnName { get; set; }

        /// <summary>
        /// Gets the Foreign Key table.
        /// </summary>
        /// <value>The Foreign Key table.</value>
        public Table FKTable { get; set; }

        /// <summary>
        /// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
        /// </returns>
        public override string ToString()
        {
            return string.Format("{0}", ColumnName);
        }
    }
}